/**
  * Created by dl
  */

import akka.actor.{Actor, ActorLogging}
import akka.cluster.Cluster
import akka.cluster.ClusterEvent._

class WorkerActor extends Actor with ActorLogging {

  private val cluster = Cluster(context.system)


  override def preStart(): Unit = {
    //    订阅事件
    cluster.subscribe(self, initialStateMode = InitialStateAsEvents,
      classOf[MemberEvent], classOf[ReachabilityEvent])
  }

  override def postStop(): Unit = cluster.unsubscribe(self)

  def receive: Receive = {
    case MemberWeaklyUp(member) =>
      log.info(s"Member is WeaklyUp: $member, actor me: $self")
    case MemberUp(member) => //集群成员状态刚设为了Up
      log.info(s"Member is Up: $member, actor me: $self")
    case MemberJoined(member) => //集群成员状态刚设为了Joining
      log.info(s"Member is Joined: $member, actor me: $self")
    case MemberLeft(member) => // 状态刚设为了leaving
      log.info(s"Member is Left: $member, actor me: $self")
    case MemberExited(member) => // 成员自己正常退出
      log.info(s"Member is Exited: $member, actor me: $self")
    // 状态成了Down，down状态一般由unreachable状态之后转移过来，
    // 由编程者自己显式设置cluster.down(member)
    // （auto-down特性可自动转移unreachable成员到down，官方不建议在生成环境中启用）
    case MemberDowned(member) =>
      log.info(s"Member is Downed: $member, actor me: $self")
    case MemberRemoved(member, previousStatus) => //成员被移出集群
      log.info(s"Member is Removed: $member after $previousStatus, actor me: $self")
    case UnreachableMember(member) => //failure-detector检测器发现了一个通信不可达的成员
      log.info(s"Member detected as unreachable: $member, actor me: $self")
      cluster.down(member.address)
    //      context.actorSelection(RootActorPath(member.address) / "user" / "otherActor") ! SomeMessage
    //共7种MemberEvent
    case ReachableMember(member) => //不可达成员重新变得可达
      log.info(s"Member is reachable again: $member, actor me: $self")

    case n: Int =>
      log.info(s"got an int: $n, actor me: ${self.path}")
      sender() ! 2 * n

    case s: String =>
      log.info(s"sender said: $s, actor me: ${self.path}")

    case any =>
      log.info(s"what is it? :$any, actor me: ${self.path}")
  }
}